package cn.rocksolid.sport.assist.idcard;

import cn.rocksolid.sport.assist.entity.IdCardEntity;
import cn.rocksolid.sport.common.Constant.Gender;
import cn.rocksolid.sport.common.error.RSE;
import cn.rocksolid.sport.common.error.RockSolidException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

public class AliYunIdCardVerifier extends AbstractIdCardVerifier {

  private static final String CONF_APP_CODE = "app-code";
  private static final String CONF_URL = "url";

  private static final String RESP_STATUS = "status";
  private static final String RESP_MSG = "msg";
  private static final String RESP_IDCARD = "idCard";
  private static final String RESP_NAME = "name";
  private static final String RESP_SEX = "sex";
  private static final String RESP_AREA = "area";
  private static final String RESP_PROVINCE = "province";
  private static final String RESP_CITY = "city";
  private static final String RESP_PREFECTURE = "prefecture";
  private static final String RESP_BIRTHDAY = "birthday";
  private static final String RESP_ADDR_CODE = "addrCode";
  private static final String RESP_LAST_CODE = "lastCode";

  private final HttpHeaders verifyHeaders;
  private final HttpHeaders verifyWithPhotoHeaders;

  private final RestTemplate restTemplate = new RestTemplate();

  public AliYunIdCardVerifier(Map<String, String> config) {
    super(config);
    this.verifyHeaders = new HttpHeaders();
    this.verifyHeaders.set(HttpHeaders.AUTHORIZATION, "APPCODE " + config.get(CONF_APP_CODE));
    this.verifyWithPhotoHeaders = new HttpHeaders();
    this.verifyWithPhotoHeaders.set(HttpHeaders.AUTHORIZATION, "APPCODE " + config.get(CONF_APP_CODE));
    this.verifyWithPhotoHeaders.set(HttpHeaders.CONTENT_TYPE,
                                    "application/x-www-form-urlencoded; charset=UTF-8");
  }

  @Override
  public IdCardEntity verify(String number, String name) {
    ResponseEntity<String> response = restTemplate.exchange(config.get(CONF_URL), HttpMethod.GET,
                                                            new HttpEntity<>(verifyHeaders), String.class, number,
                                                            name);
    if (HttpStatus.OK != response.getStatusCode() || StringUtils.isBlank(response.getBody())) {
      throw new RockSolidException(RSE.HTTP_COMM_ERR);
    }
    JSONObject jsonResult = JSON.parseObject(response.getBody());
    IdCardEntity idCard = new IdCardEntity();
    idCard.setValid("01".equals(jsonResult.get(RESP_STATUS)));
    idCard.setMessage(jsonResult.getString(RESP_MSG));
    idCard.setNumber(jsonResult.getString(RESP_IDCARD));
    idCard.setName(jsonResult.getString(RESP_NAME));
    switch (jsonResult.getString(RESP_SEX)) {
      case "男":
        idCard.setGender(Gender.MALE);
        break;
      case "女":
        idCard.setGender(Gender.FEMALE);
        break;
      default:
        idCard.setGender(Gender.UNKNOWN);
    }
    idCard.setArea(jsonResult.getString(RESP_AREA));
    idCard.setProvince(jsonResult.getString(RESP_PROVINCE));
    idCard.setCity(jsonResult.getString(RESP_CITY));
    idCard.setDistrict(jsonResult.getString(RESP_PREFECTURE));
    idCard.setBirthday(jsonResult.getString(RESP_BIRTHDAY));
    idCard.setAreaCode(jsonResult.getString(RESP_ADDR_CODE));
    idCard.setLastCode(jsonResult.getString(RESP_LAST_CODE));
    return idCard;
  }

  @Override
  public IdCardEntity verifyWithPhoto(String number, String name, String photo) {
    MultiValueMap<String, Object> payload = new LinkedMultiValueMap<>();
    payload.add("name", name);
    payload.add("number", number);
    payload.add("pic", photo);
    HttpEntity<MultiValueMap<String, Object>> req = new HttpEntity<>(payload, verifyWithPhotoHeaders);
    try {
      JSONObject resp =
              restTemplate.postForObject("https://hcapi24.market.alicloudapi.com/cert/id-card/face",
                                         req, JSONObject.class);
      JSONObject respData = resp.getJSONObject("data");
      if (StringUtils.equals("0", respData.getString("code"))) {
        IdCardEntity idCard = new IdCardEntity();
        idCard.setValid(true);
        idCard.setName(name);
        idCard.setNumber(number);
        return idCard;
      }
      throw new RockSolidException(RSE.INVALID_IDCARD);
    } catch (HttpClientErrorException hcee) {
      if (400 == hcee.getRawStatusCode()) {
        throw new RockSolidException(RSE.INVALID_IDCARD, hcee);
      }
      throw new RockSolidException(RSE.HTTP_COMM_ERR, hcee);
    }
  }
}
